package tomcat;

import com.lee.HelloServlet;
import com.lee.WebXML;
import standard.HttpServlet;
import standard.HttpServletRequest;
import standard.Servlet;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private static final int PORT = 8080;//默认监听8080端口

    public static void main(String[] args) throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        //0.为了支持并发特性，使用线程池方式
        ExecutorService pool = Executors.newFixedThreadPool(8);

        initServlets();

        //1.先进行TCP协议栈监听工作
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            //2.不断进行accept，获取连接成功的连接
            while (true) {
                Socket socket = serverSocket.accept();

                //进行业务处理
                //创建一个Http 处理流程任务
                Task task = new Task(socket);

                pool.execute(task);
            }
        }

        //destroyServlet();
    }

    //用来保存，用到的所有Servlet对象的单例模式
    //key:ServletClass  Value:该Class对应的单例模式
    private static Map<String, Servlet> servlets = new HashMap<>();
    private static WebXML webXML;

    private static void initServlets() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //模拟扫描出所有的web应用
        //找到web.xml文件(目录下的WEB-INF/web.xml)--WebXML对象
        webXML = new WebXML();
        Collection<String> servletClasses = webXML.nameToClass.values();


        //实例化这些Servlet-Class，使用反射方式
        for (String servletClass : servletClasses) {
            //构建对象--使用反射
            Class<Servlet> clz = (Class<Servlet>) Class.forName(servletClass);
            Servlet servlet = clz.newInstance();
            servlet.init();//执行生命周期中init方法
            servlets.put(servletClass, servlet);//放到servlets映射关系中
        }
    }

    private static void destroyServlet() {
        //按照约定，在销毁之前，调用一次Servlet对象的process方法
        Collection<Servlet> values = servlets.values();
        for (Servlet servlet : values) {
            servlet.destroy();
        }
    }

    private static StaticResourceServlet staticResourceServlet = new StaticResourceServlet();
    private static HttpServlet notFoundServlet =new NotFoundServlet();

    public static Servlet getServletFromWebXML(String path) {//根据path路径，实例化servlet对象
        String servletName = webXML.getServletNameByUrlPattern(path);
        if (servletName == null) {
            return null;
        }
        String servletClass = webXML.getServletClassByServletName(servletName);
        if (servletClass == null) {
            return null;
        }
        Servlet servlet = servlets.get(servletClass);
        return servlet;
    }

        static HttpServlet selectServlet(HttpServletRequest req) {
        HttpServlet servlet = (HttpServlet) Server.getServletFromWebXML(req.getPath());
        if (servlet != null) {
            return servlet;
        }
        //web.xml中没有配置该url的信息
        //1.试试看是不是静态资源
        //根据req.getPath(),去特定文件夹下查看该文件是不是存在
        if (staticResourceServlet.isStaticResource(req.getPath())) {
            return staticResourceServlet;//如果是静态资源
        }
        //2.404的Servlet去处理
        return (HttpServlet) notFoundServlet;
    }
}
